<template>
  <g :id="value.id" ref="thisNode" class="flow-node node nodegroup" :transform="`translate(${x},${y})`">

    <rect
        :class="['node','node_default',selected?'node_selected':'node_default']"
        rx="5"
        ry="5"
        :fill="backgroundColor"
        :width="width"
        :height="height"
        @dblclick.stop="nodeDblclick"
        @mouseup="nodeMouseUp"
        @mousedown="nodeMouseDown"
        @contextmenu.prevent="onContextmenu"
    />
    <g
        class="node_icon_group"
        x="0"
        y="0"
        :transform="`translate(${value.iconOnRight ? width-30 : 0},0)`"
        style="pointer-events: none;"
    >
      <!--      fill-opacity="0.05"-->
      <rect
          x="1"
          y="1"
          class="node_icon_shade"
          rx="2"
          ry="2"
          width="30"
          fill="blue"
          fill-opacity="0.5"
          stroke="node"
          height="26"
      />
      <!--      旋转动画 -->
      <image
          :href="value.icon"
          :class="['node_icon',(value.runStatus) ?'node_icon_style':''] "
          x="5"
          y="0"
          width="20"
          height="30"
      />
      <path d="M 30 1 l 0 28" class="node_icon_shade_border" stroke-opacity="0.1" stroke="#000" stroke-width="1"/>
    </g>
    <text class="node_label" x="38" y="14" dy=".35em" text-anchor="start">
      {{ value.id + value.name }}
    </text>
    <g v-if="value.status && value.status.show" class="node_status_group" :transform="`translate(3,${height+3})`">
      <rect class="node_status" x="6" y="1" width="9" height="9" rx="2" ry="2" stroke-width="3"/>
      <text class="node_status_label" x="20" y="10">{{ value.status.label }}</text>
    </g>
    <polygon
        v-if="value.error"
        class="node_error"
        :points="`${width-26},3 ${width-22},-5 ${width-18},3`"
        style="fill:red;stroke:purple;stroke-width:1"
    />
    <circle
        v-if="value.changed"
        class="node_changed"
        :cx="width-10"
        cy="-1"
        r="4"
        stroke="black"
        stroke-width="1"
        fill="cyan"
    />
    <!--  上输入点  -->
    <g
        v-if="value.hasInput"
        ref="inputGroup"
        class="port_input"
        :transform="'translate('+width/2+','+ -5+')'"
    >
      <rect
          class="port"
          :class="{ 'port_hovered': value.port.inputActive }"
          rx="3"
          ry="3"
          width="10"
          height="10"
          @mousedown="portMouseDown($event, FLOW.VIEW.PORT_TYPE_INPUT)"
          @mouseup="portMouseUp($event, FLOW.VIEW.PORT_TYPE_INPUT)"
          @mouseover="portMouseOver($event, FLOW.VIEW.PORT_TYPE_INPUT)"
          @mouseout="portMouseOut($event, FLOW.VIEW.PORT_TYPE_INPUT)"
      />
    </g>
    <!--    下输出点-->
    <g
        v-if="value.hasOutput"
        ref="outputGroup"
        class="port_output"
        :transform="`translate(${width/2}, 25)`"
    >
      <rect
          class="port"
          :class="{ 'port_hovered': value.port.outputActive }"
          rx="3"
          ry="3"
          width="10"
          height="10"
          @mousedown="portMouseDown($event, FLOW.VIEW.PORT_TYPE_OUTPUT)"
          @mouseup="portMouseUp($event, FLOW.VIEW.PORT_TYPE_OUTPUT)"
          @mouseover="portMouseOver($event, FLOW.VIEW.PORT_TYPE_OUTPUT)"
          @mouseout="portMouseOut($event, FLOW.VIEW.PORT_TYPE_OUTPUT)"
      />
    </g>
  </g>
</template>

<script>

import { AppParams } from '@/utils/appParams'
import { Emitter } from "@/utils/Emitter";
import NodeConfigMixin from '../../../libs/NodeConfigMixin'
import { UpdateFlowNodeParam } from "@/api/flow/flow";
import Utils from "@/vue2-flow/src/utils/Common";

export default {
  name: 'FlowNode',
  mixins: [NodeConfigMixin],
  props: {
    value: {
      type: Object,
      deep: true,
      immediate: true,
      default: function () {
        return {
          id: '',
          label: '测试',
          hasInput: true,
          hasOutput: true,
          iconOnRight: false,
          error: false,
          changed: false,
          runStatus: false,
          status: {
            show: false,
            label: ''
          },
          rect: {
            x: 100,
            y: 125,
            w: 140,
            h: 30
          },
          icon: '',
          style: {
            color: 'silver',
            backgroundColor: '#fff'
          },
          port: {
            inputActive: false,
            outputActive: false
          }
        }
      }
    },
    selected: {
      type: Boolean,
      default: false
    }
  },
  watch: {
    value (v) {
    },
  },
  data () {
    return {
      CurrentRunNode: {},
      isDblclick: false
    }
  },
  computed: {
    /**
     * 节点背景色
     * @returns {any}
     */
    // backgroundColor () {
    //   debugger
    //   let bgc = this.value.style.backgroundColor
    //   if (Utils.IsEmpty(bgc)) {
    //     bgc = '#fff'
    //   }
    //   if (this.value.enable === 0) {
    //     bgc = '#c8c8c8'
    //   }
    //   return bgc
    // },
    // 子组件计算属性优化
    backgroundColor () {
      // 直接依赖 value.style.backgroundColor（状态管理器已正确更新）
      let bgc = this.value.style?.backgroundColor || '#fff';
      // 若 enable 为 0，覆盖背景色（优先级高于 nodeStatus）
      if (this.value.enable === 0) {
        bgc = '#c8c8c8';
      }
      return bgc;
    },
    strokeColor () {
      return this.value.style.backgroundColor
    },
    width: function () {
      return this.value.rect.w
    },
    height: function () {
      return this.value.rect.h
    },
    x: function () {
      return this.value.rect.x - this.value.rect.w / 2
    },
    y: function () {
      return this.value.rect.y - this.value.rect.h / 2
    }
  },
  mounted () {
    //Emitter.on(AppParams.JAVA_SCRIPT_EVENT.NODE_START, this.NodeRunStatus)
    Emitter.on(AppParams.JAVA_SCRIPT_EVENT.NODE_ENABLED_DISABLE, this.NodeEnabledDisable)
  },
  beforeUnmount () {
    //Emitter.off(AppParams.JAVA_SCRIPT_EVENT.NODE_START, this.NodeRunStatus)
    Emitter.off(AppParams.JAVA_SCRIPT_EVENT.NODE_ENABLED_DISABLE, this.NodeEnabledDisable)
  },
  methods: {
    NodeRunComplete (Node) {
      // this.CurrentRunNode = {}
    },
    /**
     * 节点开始事件
     * @param Node
     * @constructor
     */
    // NodeRunStatus (Node) {
    //   this.CurrentRunNode = Node
    // },
    FlowRunStatus () {
      if (this.value.enable === 0) {
        return
      }
      this.value.style.backgroundColor = '#fff'
    },
    /**
     * 节点被启用/禁用
     * @param Tarbar
     * @constructor
     */
    NodeEnabledDisable (Tarbar) {
      const Node = this.currentClickNodeMixin
      const Enable = this.value.enable === 1 ? 0 : 1
      if (Node.id === this.value.id) {
        this.value.style.backgroundColor = Enable === 1 ? '#0b9b0b' : '#4d4d4d'
        this.value.enable = Enable
        UpdateFlowNodeParam(Node.id, 'enable', Enable, () => {
        })
      }
    },
    onNodeDblclick (event) {
      // this.isDblclick = true
      // EventBus.$emit(BUS_NODE_PLC.READ, Object.assign({}, this.value))
    },
    /**
     * 右键菜单
     * @param event
     * @returns {boolean}
     */
    onContextmenu (event) {
      this.$contextmenu({
        items: [
          { label: '前进(F)' }
        ],
        event,
        customClass: 'custom-class',
        zIndex: 3,
        minWidth: 230
      })
      return false
    },
    portMouseOver (event, portType) {
      this.$emit('portMouseOver', {
        event,
        portType,
        d: this.value,
        portIndex: 0
      })
    },
    portMouseOut (event, portType) {
      this.$emit('portMouseOut', {
        event,
        portType,
        d: this.value,
        portIndex: 0
      })
    },
    portMouseUp (event, portType) {
      this.$emit('portMouseUp', {
        event,
        portType,
        d: this.value,
        portIndex: 0
      })
    },
    portMouseDown (event, portType) {
      this.$emit('portMouseDown', {
        event,
        portType,
        d: this.value,
        portIndex: 0
      })
    },
    nodeMouseUp (event) {
      this.$emit('nodeMouseUp', {
        event,
        d: this.value
      })
    },
    nodeMouseDown (event) {
      this.$emit('nodeMouseDown', {
        event,
        d: this.value
      })
    },
    nodeDblclick (event) {
      this.$emit('nodeDblclick', {
        event,
        d: this.value
      })
    }
  }
}
</script>

<style lang="less" scoped>
@import "../../flow/styles/index.less";

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.flow-node {
  .node {
    /* stroke: #999; */
    cursor: move;
    stroke-width: 2;
    //stroke: $link-color;
    .node_icon_shade {
      border-radius: 8px;
    }

    &_default {
      stroke: @link-color;
    }

    &_selected {
      stroke-width: 2;
      stroke: @node-selected-color;
    }

    &_disable {
      fill: #c8c8c8;
    }

    // todo 暂时不启用
    &_icon_style {
      animation: rotate 1s linear infinite;
      transform-origin: 15px 14px; /* 或者使用具体的像素值，例如 '50px 100px' */
    }
  }

  .node_label {
    stroke-width: 0;
    fill: #333;
    font-size: 14px;
    pointer-events: none;
    -webkit-touch-callout: none;
    user-select: none;
    overflow-x: hidden;
  }

  .node_status_group {
    .node_status_label {
      stroke-width: 0;
      fill: #888;
      font-size: 9pt;
      stroke: #000;
      text-anchor: start;
      user-select: none;
    }
  }

  .port {
    stroke: #999;
    stroke-width: 1;
    fill: #ddd;
    cursor: crosshair;

    &_hovered {
      stroke: @port-selected-color;
      fill: @port-selected-color;
    }

    &_default {
      stroke: @link-color;
      fill: @link-color;
    }
  }

}
</style>
